package org.wu.framework.lazy.orm.core.persistence.reverse.lazy.ddd;

import org.wu.framework.core.CamelAndUnderLineConverter;
import org.wu.framework.core.NormalUsedString;
import org.wu.framework.lazy.orm.core.config.ReverseEngineering;
import org.wu.framework.lazy.orm.core.config.enums.OrmArchitecture;
import org.wu.framework.lazy.orm.core.persistence.reverse.ParamDescribeList;
import org.wu.framework.lazy.orm.core.persistence.reverse.ReverseClassLazyTableEndpoint;
import org.wu.framework.lazy.orm.core.persistence.reverse.lazy.similar.DefaultAbstractJavaReverseEngineeringMapperMethod;
import org.wu.framework.translation.data.JavaKeyword;

import java.io.File;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * description
 *
 * @author 吴佳伟
 * @date 2023/02/14 14:37
 */
public class DefaultDDDLazyInfrastructureLazyJpa extends DefaultAbstractJavaReverseEngineeringMapperMethod {


    protected DefaultDDDLazyInfrastructureLazyJpa(ReverseClassLazyTableEndpoint reverseClassLazyTableEndpoint, ReverseEngineering reverseEngineering) {
        super(reverseClassLazyTableEndpoint, reverseEngineering);
    }

    @Override
    public void initImportClassName() {

        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        if (OrmArchitecture.LAZY.equals(this.getOrmArchitecture())) {
            addImportClassName("org.wu.framework.lazy.orm.database.jpa.repository.LazyJpaRepository");
            addImportClassName("org.wu.framework.lazy.orm.database.jpa.repository.annotation.*");
            addImportClassName(tableEndpoint.getPackageName() + NormalUsedString.DOT + "infrastructure.entity" + NormalUsedString.DOT + tableEndpoint.getClassName() + "DO");
        }
        String className = tableEndpoint.getClassName();
        // import DO
        addImportClassName(tableEndpoint.getPackageName() +
                NormalUsedString.DOT + "infrastructure.entity" +
                NormalUsedString.DOT + className + "DO");
    }

    /**
     * 获取 模型 class 并且将第一个字母小写
     *
     * @return 模型 class 并且将第一个字母小写
     */
    @Override
    public String getModelClassLowercaseFirstLetter() {
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        return tableEndpoint.getClass2LowName() + "DO";
    }

    /**
     * 获取 模型class
     *
     * @return 模型class
     */
    @Override
    public String getModelClassName() {
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        return tableEndpoint.getClassName() + "DO";
    }

    /**
     * 获取 模型class 完整地址
     *
     * @return 模型class 完整地址
     */
    @Override
    public String getModelClass() {
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        return tableEndpoint.getPackageName() + NormalUsedString.DOT + "infrastructure.entity" + NormalUsedString.DOT + tableEndpoint.getClassName() + "DO";
    }

    /**
     * description:  添加 class 上的注解
     * class 上的注解如  @LazyTableFieldId(name = "%s", comment = "%s")
     *
     * @author 吴佳伟
     * @date: 13.2.23 17:13
     */
    @Override
    public void initClassAnnotationPart() {
        addClassAnnotationPart("@LazyRepository");

    }

    /**
     * description:  添加 class 字段片段
     *
     * <p>@LazyTableFieldId(comment = "api参数主键")</p>
     * private Long id;
     * </p>
     *
     * @author 吴佳伟
     * @date: 13.2.23 17:13
     */
    @Override
    public void initClassFieldPart() {

    }

    /**
     * description:  添加 class
     *
     * @author 吴佳伟
     * @date: 13.2.23 17:13
     */
    @Override
    public void initClassNamePart() {

        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        String mapperName = String.format("%sLazyJpaRepository", tableEndpoint.getClassName());
        setFileName(mapperName);

        ReverseEngineering reverseEngineering = this.getReverseEngineering();
        addClassNamePart(String.format("public interface %s extends LazyJpaRepository<%sDO,Long> {" + NormalUsedString.NEWLINE, mapperName, tableEndpoint.getClassName()) + NormalUsedString.NEWLINE);


    }

    @Override
    protected String getPackage() {
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        return String.format("package %s;", tableEndpoint.getPackageName() + NormalUsedString.DOT + "infrastructure" + NormalUsedString.DOT + "jpa" + NormalUsedString.DOT + "lazy") + NormalUsedString.NEWLINE + NormalUsedString.NEWLINE;
    }

    /**
     * description:  添加 class 方法片段
     *
     * @author 吴佳伟
     * @date: 13.2.23 17:13
     */
    @Override
    public void initClassMethodPart() {
        ReverseClassLazyTableEndpoint tableEndpoint = this.getReverseClassLazyTableEndpoint();
        String className = tableEndpoint.getClassName();
        String comment = tableEndpoint.getComment();
        final String lowercaseFirstLetter = CamelAndUnderLineConverter.lowercaseFirstLetter(className);
        final String humpToLine = CamelAndUnderLineConverter.humpToLine2(className);
        String methodParamName = lowercaseFirstLetter;
        if (Arrays.stream(JavaKeyword.values()).anyMatch(javaKeyword -> javaKeyword.name().toLowerCase().equals(lowercaseFirstLetter))) {
            methodParamName = methodParamName + NormalUsedString.UNDERSCORE;
        }
        String finalMethodParamName = methodParamName;
        // 新增 insert

        addClassMethodPart(generateMethodDescribe("新增数据", ParamDescribeList
                        .of()
                        .param(String.format("%s", methodParamName), comment + "新增参数")
                        .returnParam("void", comment + "返回结果")
                )
        );
        // 添加 注解 @LazyInsert("INSERT IGNORE INTO `sys_menu` ( `id`, `name`, `url`, `icon`, `parent_id`,`parent_name`,`sort`,`status`) VALUES ({id},{name},{url},{icon},{parentId},{parentName},{sort},{status});")
        addClassMethodPart(String.format("    @LazyInsert(\"INSERT IGNORE INTO `%s`  (%s) VALUES (%s);\")",
                        humpToLine,
                        tableEndpoint.getModelLazyTableFieldEndpoints()
                                .stream()
                                .map(lazyTableFieldEndpoint -> NormalUsedString.BACKTICK + lazyTableFieldEndpoint.getColumnName() + NormalUsedString.BACKTICK).collect(Collectors.joining(NormalUsedString.COMMA)),
                        tableEndpoint.getModelLazyTableFieldEndpoints()
                                .stream()
                                .map(lazyTableFieldEndpoint -> NormalUsedString.LEFT_BRACE + finalMethodParamName + NormalUsedString.DOT + lazyTableFieldEndpoint.getName() + NormalUsedString.RIGHT_BRACE).collect(Collectors.joining(NormalUsedString.COMMA))

                )
        );
        addClassMethodPart(String.format("     void insertWith(%s %s); "
                , className, methodParamName
        ));

        // 修改

        addClassMethodPart(generateMethodDescribe("修改数据", ParamDescribeList
                        .of()
                        .param(String.format("%s", methodParamName), comment + "修改参数")
                        .param("id", "主键ID")
                        .returnParam("int", comment + "返回更新条数")
                )
        );
        // @LazyUpdate("UPDATE `sys_menu` SET  `name` = {name} WHERE `id` = {id};")
        addClassMethodPart(String.format("    @LazyUpdate(\"UPDATE `%s` SET (%s) WHERE `id` = {id};\")",
                        humpToLine,
                        tableEndpoint.getModelLazyTableFieldEndpoints()
                                .stream()
                                .map(
                                        lazyTableFieldEndpoint ->
                                                NormalUsedString.BACKTICK + lazyTableFieldEndpoint.getColumnName() + NormalUsedString.BACKTICK + NormalUsedString.EQUALS + NormalUsedString.LEFT_BRACE + lazyTableFieldEndpoint.getName() + NormalUsedString.RIGHT_BRACE

                                ).collect(Collectors.joining(NormalUsedString.COMMA))


                )
        );
        addClassMethodPart(String.format("     int updateWithId(%s %s,int id); "
                , className, methodParamName
        ));


        // 删除
        addClassMethodPart(generateMethodDescribe("根据ID删除数据", ParamDescribeList
                        .of()
                        .param("id", "主键ID")
                        .returnParam("int", comment + "返回影响条数")
                )
        );
        // @LazyDelete("DELETE FROM sys_menu  WHERE `id` = {id};")
        addClassMethodPart(String.format("    @LazyDelete(\"DELETE FROM `%s`  WHERE `id` = {id};\")",
                        humpToLine
                )
        );
        addClassMethodPart(String.format("     int removeWithId(int id); "

        ));


        // 根据ID查询
        addClassMethodPart(generateMethodDescribe("根据ID查询数据", ParamDescribeList
                        .of()
                        .param("id", "主键ID")
                        .returnParam(String.format("%s", methodParamName), comment + "返回结果")
                )
        );
        //     @LazySelect("SELECT * FROM sys_menu WHERE id ={id}")
        addClassMethodPart(String.format("    @LazySelect(\"SELECT FROM `%s`  WHERE `id` = {id};\")",
                        humpToLine
                )
        );
        addClassMethodPart(String.format("     %s findWithId(int id); "
                , className
        ));
        // 查询数据
        // jpa
        // insert
        addClassMethodPart(generateMethodDescribe("新增数据", ParamDescribeList
                .of()
                .param(String.format("%s", methodParamName), comment + "新增参数")
                .returnParam("void", comment + "返回结果")
        ) +
                String.format("     void insert(%s %s); "
                        , className, methodParamName
                ));
        // update
        addClassMethodPart(generateMethodDescribe("修改数据", ParamDescribeList
                .of()
                .param(String.format("%s", methodParamName), comment + "修改参数")
                .returnParam("int", comment + "返回更新条数")
        ) +
                String.format("     int updateById(%s %s); "
                        , className, methodParamName
                ));
        // 删除数据
        addClassMethodPart(generateMethodDescribe("根据ID删除数据", ParamDescribeList
                .of()
                .param("id", "主键ID")
                .returnParam("int", comment + "返回影响条数")
        ) +
                String.format("     int removeById(int id); "

                ));
        // 查询id
        addClassMethodPart(generateMethodDescribe("根据ID查询数据", ParamDescribeList
                .of()
                .param("id", "主键ID")
                .returnParam(String.format("%s", methodParamName), comment + "返回结果")
        ) +
                String.format("     %s findById(int id); "
                        , className
                ));


    }

    /**
     * 获取 文件module type
     *
     * @return
     */
    @Override
    protected String getModuleType() {
        return "infrastructure" + File.separator + "jpa" + File.separator + "lazy";
    }

}
